package com.yupi.springbootinit.messagecenter;

import com.yupi.springbootinit.mapper.McMessageDeliveryMapper;
import com.yupi.springbootinit.mapper.McMessageMapper;
import com.yupi.springbootinit.mapper.McProcessedLogMapper;
import com.yupi.springbootinit.model.entity.McMessage;
import com.yupi.springbootinit.model.entity.McMessageDelivery;
import com.yupi.springbootinit.model.entity.McProcessedLog;
import com.yupi.springbootinit.mq.EventEnvelope;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;

@Service
@Slf4j
public class MessagePersistService {

    @Resource
    private McProcessedLogMapper processedLogMapper;
    @Resource
    private McMessageMapper messageMapper;
    @Resource
    private McMessageDeliveryMapper deliveryMapper;
    @Resource
    private ObjectMapper objectMapper;

    @Transactional(rollbackFor = Exception.class)
    public void persist(String consumerName, EventEnvelope env) {
        // 幂等：尝试插入 processed_log（唯一键 consumer_name + event_id）
        McProcessedLog pl = new McProcessedLog();
        pl.setConsumerName(consumerName);
        pl.setEventId(env.eventId());
        pl.setStatus("SUCCESS");
        pl.setProcessedAt(new Date());
        try {
            processedLogMapper.insert(pl);
        } catch (DuplicateKeyException e) {
            log.debug("Duplicate event, skip. consumer={}, eventId={}", consumerName, env.eventId());
            return;
        }

        // 组装消息
        String title = switch (env.type()) {
            case "order.created" -> "新订单创建";
            case "task.created" -> "新任务创建";
            case "reminder.unclaimed" -> "未认领提醒";
            case "reminder.overdue" -> "逾期提醒";
            default -> env.type();
        };
        String content = "事件: " + env.type();

        String payloadJson;
        try {
            payloadJson = objectMapper.writeValueAsString(env.payload());
        } catch (Exception e) {
            payloadJson = "{\"error\":\"payload serialize failed\"}";
        }

        Date now = new Date();
        McMessage msg = new McMessage();
        msg.setEventId(env.eventId());
        msg.setType(env.type());
        msg.setTitle(title);
        msg.setContent(content);
        msg.setPayload(payloadJson);
        msg.setSeverity("INFO");
        msg.setCreatedAt(now);
        msg.setUpdatedAt(now);
        messageMapper.insert(msg);

        // 推断接收者：优先部门(departmentId)，否则用户(createdBy)
        Long receiverId = null;
        String receiverType = null;
        try {
            if (env.payload() instanceof Map<?, ?> m) {
                Object dept = m.get("departmentId");
                if (dept instanceof Number) {
                    receiverType = "DEPT";
                    receiverId = ((Number) dept).longValue();
                }
                if (receiverId == null) {
                    Object user = m.get("createdBy");
                    if (user instanceof Number) {
                        receiverType = "USER";
                        receiverId = ((Number) user).longValue();
                    }
                }
            }
        } catch (Exception ignore) {}

        if (receiverId != null && receiverType != null) {
            McMessageDelivery d = new McMessageDelivery();
            d.setMessageId(msg.getId());
            d.setReceiverType(receiverType);
            d.setReceiverId(receiverId);
            d.setStatus("UNREAD");
            d.setCreatedAt(now);
            d.setUpdatedAt(now);
            deliveryMapper.insert(d);
        }
    }
}